package com.ndood.admin.service.system.impl;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import com.ndood.admin.core.constaints.AdminErrCode;
import com.ndood.admin.core.exception.AdminException;
import com.ndood.admin.core.quartz.QuartzManager;
import com.ndood.admin.core.quartz.ScheduleJob;
import com.ndood.admin.pojo.comm.dto.DataTableDto;
import com.ndood.admin.pojo.system.JobPo;
import com.ndood.admin.pojo.system.dto.JobDto;
import com.ndood.admin.pojo.system.query.JobQuery;
import com.ndood.admin.repository.system.JobRepository;
import com.ndood.admin.repository.system.manager.JobRepositoryManager;
import com.ndood.admin.service.system.SystemJobService;
import com.ndood.common.base.util.JPAUtil;

import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
public class SystemJobServiceImpl implements SystemJobService{
	@Autowired
	private JobRepositoryManager jobRepositoryManager;
	
	@Autowired
	private JobRepository jobRepository;
	
	@Autowired
	private QuartzManager quartzManager;
	
	@Override
	public DataTableDto pageUserList(JobQuery query) {
		String keywords = query.getKeywords();
		Date startTime = query.getStartTime();
		Date endTime = query.getEndTime();
		Integer pageNo = query.getPageNo();
		Integer pageSize = query.getLimit();
		
		Page<JobDto> page = jobRepositoryManager.pageJobList(keywords, startTime, endTime, pageNo, pageSize);
		return new DataTableDto(page.getContent(), page.getTotalElements());
		
	}
	@Override
	public void addJob(JobDto dto) throws Exception {
		JobPo po = new JobPo();
		dto.setCreateTime(new Date());
		dto.setUpdateTime(new Date());
		JPAUtil.childToFather(dto, po);
		jobRepository.save(po);
	
	}
	@Override
	public void batchDeleteJob(Integer[] ids) {
		for (Integer id : ids) {
			deleteJob(id);
		}
	}
	
	private void deleteJob(Integer id) {
		log.debug("Step1: 查询出任务");
		JobPo po = jobRepository.findById(id).get();
		log.debug("Step2: 删除任务和数据库");
		try {
			quartzManager.deleteJob(ScheduleJob.transfer(po));
		} catch (Exception e) {
		}
		jobRepository.deleteById(id);
		
	}
	@Override
	public JobDto getJob(Integer id) throws Exception {
		JobPo po = jobRepository.findById(id).get();
		JobDto dto = new JobDto();
		JPAUtil.fatherToChild(po, dto);
		return dto;
	
	}
	@Override
	public void updateJob(JobDto dto) throws Exception {
		JobPo po = jobRepository.findById(dto.getId()).get();
		dto.setUpdateTime(new Date());
		JPAUtil.childToFather(dto, po);
		jobRepository.save(po);
		
	}
	@Override
	public void changeJobStatus(Integer id, String status) throws Exception {
		log.debug("Step1: 查询出任务");
		JobPo po = jobRepository.findById(id).get();
		if(po==null) {
			throw new AdminException(AdminErrCode.ERR_OTHER,"任务不存在！");
		}
		
		if(ScheduleJob.STATUS_RUNNING.equals(status)) {
			log.debug("Step2: 启动任务");
			quartzManager.addJob(ScheduleJob.transfer(po));
		}else if(ScheduleJob.STATUS_NOT_RUNNING.equals(status)) {
			log.debug("Step2: 停止任务");
			quartzManager.deleteJob(ScheduleJob.transfer(po));
		}
		
		log.debug("Step3: 更新数据库");
		po.setJobStatus(status);
		po.setUpdateTime(new Date());
		jobRepository.save(po);
	
	}
	@Override
	public void initJobs() {
		log.debug("Step1: 查询出所有已经启动的任务");
		List<JobPo> list = jobRepository.findByJobStatus(ScheduleJob.STATUS_RUNNING);
		
		log.debug("Step2: 启动定时任务");
		for (JobPo job : list) {
			ScheduleJob scheduleJob = ScheduleJob.transfer(job);
			quartzManager.addJob(scheduleJob);
		}
		
	}
	@Override
	public void updateCrontabRule(JobDto dto) throws Exception {
		
		log.debug("Step1: 获取定时任务");
		JobPo po = jobRepository.findById(dto.getId()).get();
		if(po==null) {
			throw new AdminException(AdminErrCode.ERR_OTHER,"任务不存在！");
		}
		dto.setUpdateTime(new Date());
		JPAUtil.childToFather(dto, po);
		
		log.debug("Step2: 修改启动中的任务");
		if (ScheduleJob.STATUS_RUNNING.equals(po.getJobStatus())) {
			quartzManager.updateJobCron(ScheduleJob.transfer(po));
		}
		
		log.debug("Step3: 修改数据库");
		jobRepository.save(po);
		
	}
	
}